import { Shaders } from "./shaders"

export module ShaderResources {
    var vs_default: string = `
    attribute vec3 position;//顶点提供的数据
    attribute vec4 color; 
    attribute vec2 uv; 

    uniform mat4 matrix;

    varying vec4 vColor;//输出给fs的参数
    varying vec2 vUv;//输出给fs的参数2
    void main(void) 
    {
        gl_Position =matrix * vec4(position,1);// uViewProjMatrix * uModelMatrix * position;
        vColor = color;
        vUv = uv;
    }
    `;

    var fs_default: string = `
    precision mediump float;//指定浮点型精确度
    varying vec4 vColor;//从vs接收的参数
    varying vec2 vUv;//从vs接收的参数

    //uniform sampler2D texpalette;
    uniform sampler2D texmain;  //从外部设置的参数
    void main(void) 
    {

        //vec2 paluv = vec2(texture2D(texmain, vUv).r,0.5);
        //vec4 c = texture2D(texpalette,paluv);
        vec4 c = texture2D(texmain,vUv);
        gl_FragColor = vColor * c;
    }
    `;
    var fs_default_noa: string = `
    precision mediump float;//指定浮点型精确度
    varying vec4 vColor;//从vs接收的参数
    varying vec2 vUv;//从vs接收的参数

    //uniform sampler2D texpalette;
    uniform sampler2D texmain;  //从外部设置的参数
    void main(void) 
    {

        //vec2 paluv = vec2(texture2D(texmain, vUv).r,0.5);
        //vec4 c = texture2D(texpalette,paluv);
        vec4 c = texture2D(texmain,vUv);

        c.a = 1.0;
        gl_FragColor = vColor * c;
    }
    `;
    var fs_lightmap :string =`
    precision mediump float;//指定浮点型精确度
    varying vec4 vColor;//从vs接收的参数
    varying vec2 vUv;//从vs接收的参数

    uniform sampler2D texmain;  //从外部设置的参数

    lowp vec3 decode_hdr(lowp vec4 data)
    {
        lowp float power =pow( 2.0 ,data.a * 255.0 - 128.0) * 2.0 ;
        return data.rgb * power ;
    }
    void main(void) 
    {

        //vec2 paluv = vec2(texture2D(texmain, vUv).r,0.5);
        //vec4 c = texture2D(texpalette,paluv);
        vec4 c = texture2D(texmain,vUv);
        vec3 light = decode_hdr(c);
        c.rgb = light;
        c.a=1.0;
        gl_FragColor =  vColor * c;;
    }
    `;
    var fs_palette: string = `
    precision mediump float;//指定浮点型精确度
    varying vec4 vColor;//从vs接收的参数
    varying vec2 vUv;//从vs接收的参数

    uniform sampler2D texpalette;
    uniform sampler2D texmain;  //从外部设置的参数
    void main(void) 
    {
        float index = texture2D(texmain, vUv).r ;
        index = index * 255.0 /256.0; //调色板uv 到索引的映射
        vec2 paluv = vec2(index,0);
        vec4 c = texture2D(texpalette,paluv);
        gl_FragColor = vColor * c;
    }
    `;

    var fs_lut_pal:string =`
        precision mediump float;//指定浮点型精确度
        varying vec4 vColor;//从vs接收的参数
        varying vec2 vUv;//从vs接收的参数

        uniform sampler2D texpalette;
        uniform sampler2D texmain;  //从外部设置的参数
        uniform sampler2D texlut;//texpalette texmain texlut 是三个固定uniform
        void main(void) 
        {
            vec4 mainc = texture2D(texmain, vUv);
            int u = int(mainc.r*31.0)*32 +int(mainc.b*31.0);
            float v = (1.0-mainc.g)*63.0/64.0;
            vec2 lutuv = vec2(float(u)/1024.0,v);//将color编码到 lut 图的uv

            //下面就是查索引应用调色板
            float index = texture2D(texlut,lutuv).r;
            index = index * 255.0 /256.0; //调色板uv 到索引的映射
            vec2 paluv = vec2(index,0.5);
            vec4 c = texture2D(texpalette,paluv);
            gl_FragColor = vColor * c;
        }
    `;
    var fs_lutcutom_pal:string =`
    precision mediump float;//指定浮点型精确度
    varying vec4 vColor;//从vs接收的参数
    varying vec2 vUv;//从vs接收的参数

    uniform sampler2D texpalette;
    uniform sampler2D texmain;  //从外部设置的参数
    //uniform sampler2D texlut;//texpalette texmain texlut 是三个固定uniform
    uniform sampler2D texlutcustom;
    void main(void) 
    {
        vec4 mainc = texture2D(texmain, vUv);
        int u = int(mainc.r*31.0)*32 +int(mainc.b*31.0);
        float v = (1.0-mainc.g)*63.0/64.0;
        vec2 lutuv = vec2(float(u)/1024.0,v);//将color编码到 lut 图的uv

        //下面就是查索引应用调色板
        float index = texture2D(texlutcustom,lutuv).r;
        index = index * 255.0 /256.0; //调色板uv 到索引的映射
        vec2 paluv = vec2(index,0.5);
        vec4 c = texture2D(texpalette,paluv);
        gl_FragColor = vColor * c;
    }
`;
    export function InitShader(webgl: WebGLRenderingContext): void {
        var vsdef = Shaders.AddShader(webgl, Shaders.ShaderType.VertexShader, "default", vs_default, true);
        var fsdef = Shaders.AddShader(webgl, Shaders.ShaderType.FragmentShader, "default", fs_default, true);

        if (vsdef != null && fsdef != null)
            Shaders.LinkShader(webgl, "default", vsdef, fsdef);

        var fsdef_noa = Shaders.AddShader(webgl, Shaders.ShaderType.FragmentShader, "default_noa", fs_default_noa, true);

        if (vsdef != null && fsdef_noa != null)
            Shaders.LinkShader(webgl, "default_noa", vsdef, fsdef_noa);
            
        var fspal = Shaders.AddShader(webgl, Shaders.ShaderType.FragmentShader, "palette", fs_palette, true);
        if (vsdef != null && fspal != null)
        Shaders.LinkShader(webgl, "palette", vsdef, fspal);


        var fslutworld_pal = Shaders.AddShader(webgl, Shaders.ShaderType.FragmentShader,"lut_pal", fs_lut_pal, true);
        if (vsdef != null && fslutworld_pal != null)
        Shaders.LinkShader(webgl, "lut_palette", vsdef, fslutworld_pal);

        var fslutcustom_pal = Shaders.AddShader(webgl, Shaders.ShaderType.FragmentShader,"lutcustom_pal", fs_lutcutom_pal, true);
        if (vsdef != null && fslutcustom_pal != null)
        Shaders.LinkShader(webgl, "lutcustom_palette", vsdef, fslutcustom_pal);

        var fslight = Shaders.AddShader(webgl, Shaders.ShaderType.FragmentShader, "lightmap", fs_lightmap, true);
        if (vsdef != null && fslight != null)
        Shaders.LinkShader(webgl, "lightmap", vsdef, fslight);


    }
}